/*
vision.c
offer vision comunication api and deal with
designed by lunanting

------------------------
2020-08-10 20:36:44
create file
------------------------
*/

#include "vision.h"
#include "../../bsp/cli_cmd.h"
#include "../../bsp/xp_uart.h"
#include "string.h"
#include "aos/kernel.h"
#include "stdarg.h"
#include "stdio.h"
#include "../voice.h"

static VISION_class vision={0};
static char send_buf[XP_MESSAGE_RECV_BUFF_SIZE]={0};


/*
init vision module
base on uart port
param:
    port:uart port
    speed:uart speed
return:
    0=success
*/
int xp_vision_init(u8 port,int speed){
    vision.uart.port=port;
    vision.uart.config.baud_rate=speed;
    vision.uart.config.data_width=DATA_WIDTH_8BIT;
    vision.uart.config.parity=NO_PARITY;
    vision.uart.config.stop_bits=STOP_BITS_1;
    vision.uart.config.flow_control=FLOW_CONTROL_DISABLED;
    vision.uart.config.mode=MODE_TX_RX;

    if(hal_uart_init(&vision.uart)!=0){
        println("vision uart init fail~~");
        return -1;
    }
    void xp_vision_recive_thread(void *arg);
    aos_task_new(" vision recive",xp_vision_recive_thread,NULL,2048);
    aos_sem_new(&vision.sem,1);
    xp_voice_init();
    vision.init=1;
    println("vision module uart init success!");
    return 0;
}


/*
uart recove deal with
param:
    str:string data
*/
void __weak xp_vision_recive_deal(char *str){
    println("Recive from vision board:%s",str);
}

/*
split message package
*/
char* xp_vision_split_message(char*rec,char*bufout)
{
    int len=strlen(rec);
    char *p = NULL;
    int end=0;

    if(rec == NULL)
    {
     return NULL;
    }
    if(strstr(rec,"xp vision")==rec)
    {
      p = strstr(rec,"\\r\\n");
      end=4;
	  if(p==NULL){
		  p = strstr(rec,"\r\n");
          end=2;
	  }
      if(p == NULL)
      {
        
        return NULL;
      }
      else
      {
        memcpy(bufout,rec,p-rec+end);
      }
      if((p+end-rec)>=len){
          return NULL;
      }
        rec = p+end;
        return rec;
    }
    else
    {
        return NULL;
    }
}



/*
recive vision data deal with thread
param:
    str:string data
*/
void xp_vision_recive_thread(void *arg){
    char rec[XP_MESSAGE_RECV_BUFF_SIZE]={0};
    int rec_len=0;
    char bufout[XP_MESSAGE_RECV_BUFF_SIZE]={0};
    char *p = NULL;
    u8 i = 0;
    while(true){
        xp_uart_recive(&vision.uart,(u8 *)rec,sizeof(bufout)-1,&rec_len,10);
        // if  (rec_len != 118 && rec_len != 102 && rec_len != 82) println("xp_uart_recive[%d]: %s ",rec_len, rec);   // 打印除心跳和引导外的通信数据
        p =rec;
        i = 0;
        if(strstr(rec,"xp vision msg")==rec){
            while((p != NULL)&&(*p != 0))       // 由于接收的数据可能出现错误导致正常分割数据失败，从而使得bufout溢出
            {
                p = xp_vision_split_message(p,bufout);
                // printf("chaide shunxu is %d  %s\n\r",i,bufout);
                xp_vision_recive_deal(bufout);
                memset(bufout,0,sizeof(bufout));
                i++;
            }
        }
        else{
            if(strstr(rec,"xp vision")==rec){
            
                xp_vision_recive_deal(rec);
            }
        }
        memset(rec,0,sizeof(rec));
        // memset(rec2,0,rec_len);
        
    }
}


/*
vision uart send
param：
    format string
return：
    0=success
*/
int xp_vision_println(const char *str,...){
    int ret = 0;

    if(aos_sem_wait(&vision.sem,200)!=0)return -1;
    va_list va;
    va_start(va,str);
    vsnprintf(send_buf,sizeof(send_buf)-3,str,va);
    va_end(va);
    strcat(send_buf,"\r\n");
    ret = hal_uart_send(&vision.uart,send_buf,strlen(send_buf),100);
    aos_msleep(100);
    aos_sem_signal(&vision.sem);
    return ret;
}



/*
vision send data
param:
    data: send data
    len:send data length
*/
void xp_vision_send(char *data,int len){
    if(aos_sem_wait(&vision.sem,500)!=0)return;
    hal_uart_send(&vision.uart,send_buf,strlen(send_buf),20);
    aos_sem_signal(&vision.sem);
}


/*
vision send cmd
param:
    cmd: cmd string
    param:param string NULL=no param
return:
    0=success
*/
int xp_vision_cmd(char *cmd,char *param){
    if(param==NULL){
        return xp_vision_println("xp vision %s",cmd);
    }
    else{
        return xp_vision_println("xp vision %s %s",cmd,param);
    }
}

/**************************debug***********************/
/*
vision debug
*/
int xp_vision_debug(char *type,char *fun,char *param){
    if(strcmp(type,"vision")!=0)return 0;
    else{
        xp_vision_println("xp vision %s %s",fun,param);
        println("Send cmd to vision board:xp vision %s %s",fun,param);
    }
    return 1;
}


//end of the file
